package com.atguigu.gulimall.search.Thread;

import java.util.concurrent.*;

/**
 * 1，线程开启，执行任务
 * 2，处理线程结果，感知错误，处理异常
 * 3，线程串行化，多个线程之间的关系调度
 *
 * 两任务组合，都要完成
 *         //runAfterBothAsyn
 *         //thenAcceptBothAsync
 *         //thenCombineAsync
 * 两任务组合，一个完成
 *         //runAfterEitherAsync
 *         //acceptEitherAsync
 *         //applyToEitherAsync
 * @author guoch0613@163.com
 * @Description 创建线程四种方式
 * @create 2021-04-10 18:44
 */
public class ThreadTests {
    public static ExecutorService executorService = Executors.newFixedThreadPool(10);


    public static ExecutorService executor = new ThreadPoolExecutor(
            2,
            5,
            3L,
            TimeUnit.SECONDS,
            new ArrayBlockingQueue<Runnable>(3),
            Executors.defaultThreadFactory(),
            //new ThreadPoolExecutor.DiscardPolicy()
            new ThreadPoolExecutor.DiscardOldestPolicy()
            //new ThreadPoolExecutor.CallerRunsPolicy()
            // new ThreadPoolExecutor.AbortPolicy()
    );

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        System.out.println("主线程开始");
        CompletableFuture<String> futureImg = CompletableFuture.supplyAsync(() -> {
            System.out.println("查询商品的图片信息");
            return "hello.jpg";
        }, executor);

        CompletableFuture<String> futureAttr = CompletableFuture.supplyAsync(() -> {
            System.out.println("查询商品的属性");
            return "黑色+256G";
        }, executor);

        CompletableFuture<String> futureDesc = CompletableFuture.supplyAsync(() -> {
            System.out.println("查询商品的介绍");
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "华为";
        }, executor);

        CompletableFuture<Void> allOf = CompletableFuture.allOf(futureImg, futureAttr, futureDesc);
        allOf.get();//等待所有的线程执行完
        System.out.println("主线程结束");
//        CompletableFuture<Object> future01 = CompletableFuture.supplyAsync(() -> {
//            System.out.println("线程一开始");
//            int res = 10 / 2;
//            System.out.println("线程一结束：" + Thread.currentThread().getId());
//            return res;
//        }, executor);
//
//        CompletableFuture<Object> future02 = CompletableFuture.supplyAsync(() -> {
//            System.out.println("线程二开始");
//            try {
//                Thread.sleep(3000);
//                System.out.println("线程二结束：" + Thread.currentThread().getId());
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//            return "juc";
//        }, executor);

        //runAfterEitherAsync不感知前面线程的结果
//        future01.runAfterEitherAsync(future02,()->{
//            System.out.println("线程三开始");
//            System.out.println("线程三结束：" + Thread.currentThread().getId());
//        });
        //acceptEitherAsync接受其中一个结果
//        future01.acceptEitherAsync(future02,res->{
//            System.out.println("线程三开始"+res);
//            System.out.println("线程三结束：" + Thread.currentThread().getId());
//        });
        //接收前面返回值，自己也有返回值
//        CompletableFuture<String> future = future01.applyToEitherAsync(future02, res -> res + "haha", executor);


        //thenCombineAsync能感受到前两个任务的返回值，并且自己也有返回值
//        CompletableFuture<String> future = future01.thenCombineAsync(future02, (f, t) -> {
//            return f + "-->>" + t + "hello";
//        }, executor);

//        System.out.println("线程结束取得结果：" + future.get());

        //thenRunAsync不接收上一个结果，并且上一个出异常不执行 .thenRunAsync(() -> System.out.println("线程2执行"), executor);
        //thenAcceptAsync接受上一个结果，但是不返回结果thenAcceptAsync((res)->System.out.println("线程2执行"+res),executor);
//        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
//            System.out.println("开始线程");
//            int res = 10 / 2;
//            System.out.println("线程结束：" + Thread.currentThread().getId());
//            return res;
//        }, executor).thenApplyAsync((res) -> {
//            System.out.println("线程2执行" + res);
//            return "hello" + res;
//        }, executor);

        //runAfterBothAsyn感知不到前面任务得返回值
//        future01.runAfterBothAsync(future02,()->{
//            System.out.println("线程三开始");
//        },executor);

        //thenAcceptBothAsync能感知前面两个任务的返回值，自己没有返回值
//        future01.thenAcceptBothAsync(future02,(f,t)->{
//            System.out.println("线程三开始"+f+"-->>"+t);
//        },executor);

//        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
//            System.out.println("开始线程");
//            int res = 10 / 0;
//            System.out.println("线程结束：" + Thread.currentThread().getId());
//            return res;
//        }, executor).handle((res,exc)->{
//            if (res!=null){
//                return res;
//            }
//
//            if (exc!=null){
//                return 0;
//            }
//            return 0;
//        });
//                .whenComplete((res, execp) -> {
//
//            System.out.println("线程结束取得结果：" + res + "异常是:" + execp);
//        }).exceptionally(throwable ->10);
        //whenComplete接收函数型接口,参数一返回结果,参数二异常,但是不处理
//exceptionally处理异常

    }

    public static void thread01() {
        System.out.println("主线程开始");
//        Thread01 thread01 = new Thread01();
//        thread01.run();

//        new Thread(new Thread01()).start();
//        new Thread(futureTask,"张三").start();

        FutureTask<Integer> futureTask = new FutureTask<>(new callable01());
        executorService.submit(futureTask);

        int res1 = 100 / 2;
        System.out.println("主线程计算结果是：" + res1);

    }

    public static class Thread01 extends Thread {
        @Override
        public void run() {
            try {
                System.out.println("开始线程");
                int res = 10 / 2;
                Thread.sleep(10000);
                System.out.println("计算结果是：" + res);
                System.out.println("线程结束：" + Thread.currentThread().getId());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static class Runable01 implements Runnable {

        @Override
        public void run() {
            try {
                System.out.println("开始线程");
                int res = 10 / 2;
                Thread.sleep(10000);
                System.out.println("计算结果是：" + res);
                System.out.println("线程结束：" + Thread.currentThread().getId());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static class callable01 implements Callable<Integer> {

        @Override
        public Integer call() throws Exception {
            try {
                System.out.println("开始线程");
                int res = 10 / 2;
                Thread.sleep(1000);
                System.out.println("计算结果是：" + res);
                System.out.println("线程结束：" + Thread.currentThread().getId());
                return res;
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return 1;
        }
    }
}
